<template>
  <n-form
    :model="formParams"
    :rules="rules"
    ref="formRef"
    label-placement="left"
    :label-width="100"
    require-mark-placement="left"
  >
    <n-divider title-placement="left" class="mt-3">基本设置</n-divider>

    <n-form-item label="类型" path="menu_type">
      <n-radio-group v-model:value="formParams.menu_type" name="menuTypeGroup">
        <n-radio-button :key="0" :value="0">目录</n-radio-button>
        <n-radio-button :key="1" :value="1">菜单</n-radio-button>
        <n-radio-button :key="2" :value="2">按钮</n-radio-button>
      </n-radio-group>
    </n-form-item>

    <n-form-item :label="`上级${getTypeLable}`" path="parent_id">
      <n-tree-select
        key-field="id"
        label-field="menu_name"
        :options="getPermissionList"
        clearable
        v-model:value="formParams.parent_id"
      />
    </n-form-item>

    <n-grid x-gap="12" :cols="2">
      <n-gi>
        <n-form-item :label="`${getTypeLable}名称`" path="menu_name">
          <n-input :placeholder="`${getTypeLable}名称`" v-model:value="formParams.menu_name" />
        </n-form-item>
      </n-gi>
      <n-gi>
        <n-form-item :label="`${getTypeLable}图标`" path="icon">
          <template #label>
            <span>
              <n-tooltip trigger="hover">
                <template #trigger>
                  <n-icon :size="18" class="mr-1 -mt-1 text-gray-400 cursor-pointer">
                    <QuestionCircleOutlined />
                  </n-icon>
                </template>
                {{ getTypeLable }}图标，填写图标组件名称，需在 `src\router\router-icons.ts`
                中导入并映射
              </n-tooltip>
              <span>{{ getTypeLable }}图标</span>
            </span>
          </template>
          <n-input :placeholder="`${getTypeLable}图标映射名称`" v-model:value="formParams.icon" />
        </n-form-item>
      </n-gi>
    </n-grid>

    <n-grid x-gap="12" :cols="2">
      <n-gi>
        <n-form-item path="route_url" v-if="formParams.menu_type != 2">
          <template #label>
            <span>
              <n-tooltip trigger="hover">
                <template #trigger>
                  <n-icon :size="18" class="mr-1 -mt-1 text-gray-400 cursor-pointer">
                    <QuestionCircleOutlined />
                  </n-icon>
                </template>
                路由地址，如：user
              </n-tooltip>
              <span>路由地址</span>
            </span>
          </template>
          <n-input placeholder="路由地址" v-model:value="formParams.route_url" />
        </n-form-item>
      </n-gi>
      <n-gi>
        <n-form-item path="route_name" v-if="formParams.menu_type != 2">
          <template #label>
            <span>
              <n-tooltip trigger="hover">
                <template #trigger>
                  <n-icon :size="18" class="mr-1 -mt-1 text-gray-400 cursor-pointer">
                    <QuestionCircleOutlined />
                  </n-icon>
                </template>
                对应路由配置文件中 `name` 只能是唯一性，配置 `http(s)://` 开头地址 则会新窗口打开
              </n-tooltip>
              <span>路由名称</span>
            </span>
          </template>
          <n-input placeholder="路由地址" v-model:value="formParams.route_name" />
        </n-form-item>
      </n-gi>
    </n-grid>

    <n-grid x-gap="12" :cols="2" v-if="formParams.menu_type > 0">
      <n-gi>
        <n-form-item path="permission_code">
          <template #label>
            <span>
              <n-tooltip trigger="hover">
                <template #trigger>
                  <n-icon :size="18" class="mr-1 -mt-1 text-gray-400 cursor-pointer">
                    <QuestionCircleOutlined />
                  </n-icon>
                </template>
                权限标识，也是权限字符，比如 `system:menu:list`
              </n-tooltip>
              <span>权限标识</span>
            </span>
          </template>
          <n-input
            placeholder="权限标识 system:user:add"
            v-model:value="formParams.permission_code"
          />
        </n-form-item>
      </n-gi>
      <n-gi>
        <n-form-item path="permission_name">
          <template #label>
            <span>
              <n-tooltip trigger="hover">
                <template #trigger>
                  <n-icon :size="18" class="mr-1 -mt-1 text-gray-400 cursor-pointer">
                    <QuestionCircleOutlined />
                  </n-icon>
                </template>
                权限名称 对应 权限标识 `中文名称`
              </n-tooltip>
              <span>权限名称</span>
            </span>
          </template>
          <n-input placeholder="权限名称 添加用户" v-model:value="formParams.permission_name" />
        </n-form-item>
      </n-gi>
    </n-grid>

    <n-grid x-gap="12" :cols="2">
      <n-gi v-if="formParams.menu_type != 2">
        <n-form-item path="redirect">
          <template #label>
            <span>
              <n-tooltip trigger="hover">
                <template #trigger>
                  <n-icon :size="18" class="mr-1 -mt-1 text-gray-400 cursor-pointer">
                    <QuestionCircleOutlined />
                  </n-icon>
                </template>
                默认跳转路由地址，如：`/system/menu/menu` 多级路由情况下适用
              </n-tooltip>
              <span>默认路由</span>
            </span>
          </template>
          <n-input placeholder="默认跳转路由地址" v-model:value="formParams.redirect" />
        </n-form-item>
      </n-gi>
      <n-gi v-if="formParams.menu_type != 2">
        <n-form-item label="显示排序" path="orderNum">
          <n-input-number
            placeholder="显示排序"
            v-model:value="formParams.order_num"
            class="w-full"
          />
        </n-form-item>
      </n-gi>
    </n-grid>

    <n-grid x-gap="12" :cols="1" v-if="formParams.menu_type != 2">
      <n-gi>
        <n-form-item path="component">
          <template #label>
            <span>
              <n-tooltip trigger="hover">
                <template #trigger>
                  <n-icon :size="18" class="mr-1 -mt-1 text-gray-400 cursor-pointer">
                    <QuestionCircleOutlined />
                  </n-icon>
                </template>
                访问的组件路径，如：`/system/menu/menu`，默认在`views`目录下，默认 `LAYOUT`
                如果是多级菜单 `ParentLayout`
              </n-tooltip>
              <span>组件路径</span>
            </span>
          </template>
          <n-input placeholder="组件路径" v-model:value="formParams.component" />
        </n-form-item>
      </n-gi>
    </n-grid>

    <n-divider title-placement="left" class="mt-3">功能设置</n-divider>

    <n-grid x-gap="12" :cols="2">
      <n-gi>
        <n-form-item path="status">
          <template #label>
            <span>
              <n-tooltip trigger="hover">
                <template #trigger>
                  <n-icon :size="18" class="mr-1 -mt-1 text-gray-400 cursor-pointer">
                    <QuestionCircleOutlined />
                  </n-icon>
                </template>
                选择停用则路由将不会出现在侧边栏，也不能被访问
              </n-tooltip>
              <span>{{ getTypeLable }}状态</span>
            </span>
          </template>
          <n-radio-group v-model:value="formParams.status" name="statusGroup">
            <n-radio-button :key="0" :value="0">正常</n-radio-button>
            <n-radio-button :key="1" :value="1">停用</n-radio-button>
          </n-radio-group>
        </n-form-item>
      </n-gi>
      <n-gi v-if="formParams.menu_type != 2">
        <n-form-item label="根路由" path="isRoot">
          <template #label>
            <span>
              <n-tooltip trigger="hover">
                <template #trigger>
                  <n-icon :size="18" class="mr-1 -mt-1 text-gray-400 cursor-pointer">
                    <QuestionCircleOutlined />
                  </n-icon>
                </template>
                如果使用 `顶部混合菜单`，必须传 true，否则左侧会显示异常
              </n-tooltip>
              <span>根路由</span>
            </span>
          </template>
          <n-switch v-model:value="formParams.is_root" />
        </n-form-item>
      </n-gi>
    </n-grid>

    <n-grid x-gap="12" :cols="2" v-if="formParams.menu_type != 2">
      <n-gi>
        <n-form-item path="isVisible">
          <template #label>
            <div>
              <n-tooltip trigger="hover">
                <template #trigger>
                  <n-icon :size="18" class="mr-1 -mt-1 text-gray-400 cursor-pointer">
                    <QuestionCircleOutlined />
                  </n-icon>
                </template>
                选择隐藏则路由将不会出现在侧边栏，但仍然可以访问
              </n-tooltip>
              <span>显示状态</span>
            </div>
          </template>
          <n-radio-group v-model:value="formParams.is_visible" name="isVisibleGroup">
            <n-radio-button :key="0" :value="0">显示</n-radio-button>
            <n-radio-button :key="1" :value="1">隐藏</n-radio-button>
          </n-radio-group>
        </n-form-item>
      </n-gi>
      <n-gi>
        <n-form-item path="isCache">
          <template #label>
            <div>
              <n-tooltip trigger="hover">
                <template #trigger>
                  <n-icon :size="18" class="mr-1 -mt-1 text-gray-400 cursor-pointer">
                    <QuestionCircleOutlined />
                  </n-icon>
                </template>
                选择是则会被`keep-alive`缓存，需要匹配组件的`name`和地址保持一致
              </n-tooltip>
              <span>是否缓存</span>
            </div>
          </template>
          <n-radio-group v-model:value="formParams.is_cache" name="isCacheGroup">
            <n-radio-button :key="0" :value="0">缓存</n-radio-button>
            <n-radio-button :key="1" :value="1">不缓存</n-radio-button>
          </n-radio-group>
        </n-form-item>
      </n-gi>
    </n-grid>

    <n-grid x-gap="12" :cols="2" v-if="formParams.menu_type != 2">
      <n-gi v-if="formParams.menu_type != 2">
        <n-form-item label="是否外链" path="is_frame">
          <template #label>
            <span>
              <n-tooltip trigger="hover">
                <template #trigger>
                  <n-icon :size="18" class="mr-1 -mt-1 text-gray-400 cursor-pointer">
                    <QuestionCircleOutlined />
                  </n-icon>
                </template>
                选择是外部地址需以`http(s)://`开头
              </n-tooltip>
              <span>是否外链</span>
            </span>
          </template>
          <n-radio-group v-model:value="formParams.is_frame" name="isFrameGroup">
            <n-radio-button :key="0" :value="0">是</n-radio-button>
            <n-radio-button :key="1" :value="1">否</n-radio-button>
          </n-radio-group>
        </n-form-item>
      </n-gi>
      <n-gi>
        <n-form-item label="简化路由" path="always_show">
          <template #label>
            <span>
              <n-tooltip trigger="hover">
                <template #trigger>
                  <n-icon :size="18" class="mr-1 -mt-1 text-gray-400 cursor-pointer">
                    <QuestionCircleOutlined />
                  </n-icon>
                </template>
                取消自动计算根路由模式 开启之后，当菜单子菜单只有1个的时候，会直接显示子菜单
              </n-tooltip>
              <span>简化路由</span>
            </span>
          </template>
          <n-switch v-model:value="formParams.always_show" />
        </n-form-item>
      </n-gi>
    </n-grid>
    <n-grid x-gap="12" :cols="1" v-if="formParams.menu_type != 2">
      <n-gi>
        <n-form-item
          label="外部地址"
          path="frame_src"
          v-if="formParams.menu_type != 2 && formParams.is_frame === 0"
        >
          <n-input placeholder="内联外部地址" v-model:value="formParams.frame_src" />
        </n-form-item>
      </n-gi>
    </n-grid>

    <n-form-item class="submit-form-item" v-if="isShowSubmit">
      <n-button type="primary" :loading="subLoading" @click="formSubmit">保存修改</n-button>
    </n-form-item>
  </n-form>
</template>

<script lang="ts" setup>
  import { ref, computed } from 'vue';
  import { useMessage } from 'naive-ui';
  import { addMenu, editMenu } from '@/api/system/menu';
  import { QuestionCircleOutlined } from '@vicons/antd';

  const emit = defineEmits(['change']);

  const props = defineProps({
    permissionList: {
      type: Array,
    },
    isShowSubmit: {
      type: Boolean,
      defalut: false,
    },
  });

  const message = useMessage();
  const formRef: any = ref(null);
  const subLoading = ref(false);

  const defaultValueRef = () => ({
    id: null,
    parent_id: 0,
    active_menu: '',
    affix: false,
    always_show: true,
    icon: '',
    is_cache: 1,
    is_frame: 1,
    is_visible: 0,
    menu_name: '',
    menu_type: 0,
    open_type: 1,
    status: 0,
    order_num: null,
    permission_code: '',
    permission_name: '',
    query: '',
    route_url: '',
    route_name: '',
    redirect: '',
    component: '', //目录默认 LAYOUT 多级菜单目录 设置 ParentLayout
  });

  const formParams: any = ref(defaultValueRef());

  const getPermissionList = computed(() => {
    return props.permissionList;
  });

  const getTypeLable = computed(() => {
    const typsStr = ['目录', '菜单', '按钮'];
    return typsStr[formParams.value.menu_type];
  });

  const rules = {
    menu_name: {
      required: true,
      message: `${getTypeLable.value}名称`,
      trigger: 'blur',
    },
    route_url: {
      required: true,
      message: '路由地址不能为空',
      trigger: 'blur',
    },
    component: {
      required: true,
      message: '组件路径不能为空',
      trigger: 'blur',
    },
    route_name: {
      required: true,
      message: '路由名称不能为空',
      trigger: 'blur',
    },
    frame_src: {
      required: true,
      message: '外部地址不能为空',
      trigger: 'blur',
    },
  };

  function setData(data) {
    formParams.value = data;
    formRef.value?.restoreValidation();
  }

  function formSubmit() {
    subLoading.value = true;
    formRef.value.validate((errors) => {
      if (!errors) {
        if (!formParams.value.id) {
          addMenu(formParams.value)
            .then(() => {
              subLoading.value = false;
              message.success('添加成功');
              handleReset();
              emit('change');
            })
            .catch(() => {
              subLoading.value = false;
            });
        } else {
          editMenu(formParams.value)
            .then(() => {
              subLoading.value = false;
              message.success('修改成功');
              handleReset();
              emit('change');
            })
            .catch(() => {
              subLoading.value = false;
            });
        }
      } else {
        subLoading.value = false;
        message.error('请填写完整信息');
      }
    });
  }

  function handleReset() {
    formRef.value.restoreValidation();
    formParams.value = Object.assign(formParams.value, defaultValueRef());
  }

  defineExpose({
    formSubmit,
    handleReset,
    setData,
  });
</script>

<style lang="less" sctep>
  .submit-form-item {
    margin-left: 100px;
  }
</style>
